#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
# define slots 10
FILE *flog;

int pos,tbl=1,clsions=0,choice;
struct hsh{
       char id[slots][20],pw[slots][20];
       struct hsh *nx;
       }*st=NULL;
int lprobe(int k)
{
    return k;
}
int hfn(int sum)
{
    return abs(sum%slots);
}
int hfn1(int sum)
{
    return abs((sum/slots)%slots);
}

void hasher(char us[],char pw[])
{    struct hsh *nop=st;
     if(pos==slots)
     {          pos=0;
                tbl++;
                fprintf(flog,"\nMoved to table no %d",tbl);
                }
     int k,m=0,sum=0,h;
     for(k=tbl;k>1;k--)
                       nop=nop->nx;
     
     for(;us[m]!='\0';m++)
     {
                          if(choice==3)
                                      { if(us[m]!='a'&&us[m]!='e'&&us[m]!='i'&&us[m]!='o'&&us[m]!='u'&&us[m]!='A'&&us[m]!='E'&&us[m]!='I'&&us[m]!='O'&&us[m]!='U')
                                                                                                                                                                 sum+=us[m];
                                                                                                                                                                 }
                          else
                              sum+=(char)us[m];
                              }
     k=0;
     do{if(choice==2)
                     h=hfn1(sum+lprobe(k));
                     else
                          h=hfn(sum+lprobe(k));
        if(strlen(nop->id[h])>0)clsions++;
        fprintf(flog,"\nKEY:%d",h);
        k++;
        fprintf(flog,"%s",nop->id[h]);}
        while(strlen(nop->id[h])>0);
     fprintf(flog,"\nDONE!!");
     strcpy(nop->id[h],us);
     strcpy(nop->pw[h],pw);
     pos++;
 }
 
 void inith(int n)
 {    struct hsh *nop,p;
      for(;n>=1;n--)
   {                
                    nop=NULL;
                    nop=(struct hsh *)calloc(1,sizeof(struct hsh));
                    nop->nx=st;
                    st=nop;
                    
                    }
                              
  }
void hashcheck(char us[])
{    struct hsh *nop=st;
     int chk=0,h,m=0,sum=0;
      for(;us[m]!='\0';m++)
     {
                          if(choice==3)
                                      { if(us[m]!='a'&&us[m]!='e'&&us[m]!='i'&&us[m]!='o'&&us[m]!='u'&&us[m]!='A'&&us[m]!='E'&&us[m]!='I'&&us[m]!='O'&&us[m]!='U')
                                                                                                                                                                 sum+=us[m];
                                                                                                                                                                 }
                          else
                              sum+=us[m];
                              }
     for(;nop!=NULL;nop=nop->nx)
     {                          chk=0;
                                while(chk<slots)
                                {
                                                if(choice==2)
                                                             h=hfn1(sum+lprobe(chk));
                                                             else
                                                                  h=hfn(sum+lprobe(chk));                                                      
                                                if(strcmp(us,nop->id[h])==0)
                                                {
                                                                            chk=99;
                                                                            printf("\nUID found");
                                                                            break;
                                                }
                                                else chk++;
                                }
                                if(chk==99) break;
     }
      if(chk==99)
       {
                char pw[20];
                 for(m=1;m<=3;m++)
                 {		   
                                   printf("\nEnter password:");
                                   setbuf(stdin,NULL);
                                   scanf("%s",pw);


                                   if(strcmp(pw,nop->pw[h])==0)
                                   {
                                                            printf("\nCorrect!!!");
                                                            return;
                                   }
                                   else
                                       printf("\nWrong! %d tries left",3-m);
                 }
                 printf("\n3 times wrong pass entered ......Peogram Terminating!!!!");
                 getchar();
                 exit(0);
       }
       else
       
           printf("\nWrong username!");
}
                                    
                                                
     
 void main()
 {
        char ch,c,fname[20],us[20],pw[20];
        int cnt=1,slt=slots,tables,i=0;
        FILE *f1,*f2;
        printf("\nEnter the file name(with extension):");
        scanf("%s",fname);
        printf("\nEnter:\n1.For modulo of sum of ascii values.\n2.Modulo of qoutient of sum of ascii values.\n3.Modulo of sum of ascii value of non-vowels:");
        scanf("%d",&choice); 
        f1=fopen(fname,"r");
        flog=fopen("log.txt","w");
        ch=getc(f1);
        fprintf(flog,"\nReading file:\n");
        while(ch!=EOF)
        {             
                      if(ch=='\n') cnt++;
                      ch=getc(f1);
                      }
	if(cnt%slt==0)
        	tables=cnt/slt;
	else
		tables=cnt/slt+1;
	
        fprintf(flog,"\n\n\nNumber of tables required _______%d_______",tables);
        inith(tables);
        fclose(f1);
        f2=fopen(fname,"r");
        fprintf(flog,"\nTables created!\n");
        c=getc(f2);
        while(c!=EOF&&cnt>0)
        {            i=0;
                     while(c!=' ')
                     {
                                us[i]=c;
                                i++;
                                c=getc(f2);
                                
                                }us[i]='\0';
                     i=0;
                     c=getc(f2);
                     while(c!='\n')
                     {		
                                   pw[i]=c;
                                   c=getc(f2);if(c==EOF)break;
                                   i++;
                                   }pw[i-1]='\0';
                                   c=getc(f2);
                     fprintf(flog,"\nPassing uid:%s \t pswd:%s",us,pw);
                     hasher(us,pw);}
        fclose(f2);
         struct hsh *nop=st;
         fprintf(flog,"\nHashing complete!!!\nCollisions:%d",clsions);
         printf("\nHashing complete!!!\nCollisions:%d",clsions);
         printf("\nLoad factor for last table:%f",(cnt%10)/10.0);
         i=1;
         while(nop!=NULL)
         {
                         int g;
                         fprintf(flog,"\nTable %d",i);
                         for(g=0;g<slots;g++)
                                             fprintf(flog,"\n%s||%s",nop->id[g],nop->pw[g]);
                         nop=nop->nx;
                         i++;} 
          fprintf(flog,"Collisions!!!!:::::%d",clsions);                  
          do
          {          
                     printf("\nEnter the ID:");
                     setbuf(stdin,NULL);
                     scanf("%s",us);
                     if(strlen(us)>0)
                                     hashcheck(us);
                     else
                         printf("\nEmpty not allowed!");
                     printf("\nEnter 0 to exit, any other to continue!");
                     scanf("%d",&i);}while(i!=0);
}           
